#ifndef PRIMITIVES_H
#define PRIMITIVES_H

#include "../Ray.h"
#include "../Material.h"
#include "../Color/Color.h"
#include "../Vector/Vector.h"

#include <assert.h>
#include <iostream>
using namespace std;

class Primitive{
	public:

		/* Constructor por defecto */
		Primitive();

		/* Constructor que usan las clases derivadas*/
		Primitive(const Material& m);

		/* Dado un rayo, avisa si intersecta y devuelve el punto */
		virtual hitResult intersects(const Ray& r, const double& max_d) const = 0;

		/* Requiere que el punto pertenezca al objeto */
		/* Devuelve el vector normal en ese punto, normalizado */
		virtual Vector normal(const Vector& p) const = 0;

		virtual Ray refraction(const Vector& i, const Vector& d) const = 0;

		/* Propiedades del material */
		double diffuse_reflection() const;
		double specular_reflection() const;
		double shininess() const;
		double transparency() const;
		double reflection() const;
		double refraction() const;
		double ior() const;
		Color color() const;

	protected:

		Material m;
};

class Sphere : public Primitive{
	public:
		Sphere();
		Sphere(const Vector& _c, const double& _r, const Material& m);
		hitResult intersects(const Ray& r, const double& max_d) const;
		Vector normal(const Vector& p) const;
		Ray refraction(const Vector& i, const Vector& d) const;
	private:
		Vector c;
		double r;
};

class Plane : public Primitive{
	public:
		Plane();
		Plane(const Vector& _n, const double& _d, const Material& m);
		hitResult intersects(const Ray& r, const double& max_d) const;
		Vector normal(const Vector& p) const;
		Ray refraction(const Vector& i, const Vector& d) const;
	private:
		Vector n;
		float d;
};

#endif
